<?php

class LoginController extends Controller
{
	private $clientid;
	private $cookie_file;
	private $cookies;
	private $nickname;
	
	public function beforeAction()
	{
		parent::beforeAction($this);
		$this->clientid = mt_rand(10000000, 99999999);
		$this->cookie_file = Yii::getPathOfAlias('webroot') . "/tmp/cookie";
		return TRUE;
	}
	
	public function actionIndex()
	{
		$model = new QQLogin();
		if (Yii::app()->request->getIsPostRequest()) {
			$model->attributes = Yii::app()->request->getPost('QQLogin');
			$qq = $model->username;
			$password = $model->password;
			$data = $this->checkVerify($qq);
			$need_capcha = $data[0];
			$verification_code = $data[1];
			$pt_uin = $data[2];
			$encrypt_password_str = $this->encryptPassword($password, $verification_code, $pt_uin);
			$login1_data = $this->login1($qq, $encrypt_password_str, $verification_code);
			// login1登陆成功
			if ($login1_data[0] === '0') 
			{
				$this->nickname = $login1_data[5];
			}else
			{
				throw new CException('login failed:' . $login1_data[4]);
			}
			$ptwebqq = trim($this->getCookie('ptwebqq'));
			$login2_data = $this->login2($ptwebqq);
			print_r($login2_data);
			exit;
		}
		$this->render('index', array('model'=>$model));
	}
	
	/**
	 * 获取验证码
	 * @param int $qq
	 * @return string
	 */
	public function checkVerify($qq)
	{
		$url = "https://ssl.ptlogin2.qq.com/check?uin={$qq}&appid=1003903&r=" . microtime(TRUE);
		$data = CurlRequest::makeRequest($url, array(), 'GET', $this->cookie_file);
		if (preg_match("/ptui_checkVC\('(.*)','(.*)','(.*)'\);/", $data, $verify))
		{
			return array_slice($verify, 1);
		}
	}
	
	/**
	 * 第一次登陆---验证QQ密码 
	 * @param string $qq
	 * @param string $encrypt_password_str
	 * @param string $verification_code
	 * @return array:
	 */
	public function login1($qq, $encrypt_password_str, $verification_code)
	{
		$url = "http://ptlogin2.qq.com/login?u={$qq}&p={$encrypt_password_str}&verifycode={$verification_code}&webqq_type=10&remember_uin=1&login2qq=1&aid=1003903&u1=http%3A%2F%2Fweb.qq.com%2Floginproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&h=1&ptredirect=0&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=8-38-447467&mibao_css=m_webqq&t=3&g=1";
		$data = CurlRequest::makeRequest($url, array(), 'GET', $this->cookie_file);
		if (preg_match("/ptuiCB\('(.*)','(.*)','(.*)','(.*)','(.*)',\s'(.*)'\);/U", $data, $verify))
		{
			return array_slice($verify, 1);
		}
	}
	
	/**
	 * 第二次登陆--真正的上线
	 * @param string $ptwebqq
	 * @return string
	 */
	public function login2($ptwebqq)
	{
		$url = "http://d.web2.qq.com/channel/login2";
		$param = array('r' => urlencode(json_encode(array(
			'status'=>'online',
			'ptwebqq'=>$ptwebqq,
			'passwd_sig'=>'',
			'clientid'=>$this->clientid,
			'psessionid'=>'null',
		))),);
		print_r($param);
		return CurlRequest::makeRequest($url, $param, 'POST', $this->cookie_file, array(CURLOPT_REFERER=>'http://d.web2.qq.com/proxy.html?v=20110331002&callback=2'));
	}
	
	/**
	 * 加密密码
	 * @param string $password
	 * @param string $verification_str
	 * @param string $pt_uin
	 * @return string
	 */
	public function encryptPassword($password, $verification_str, $pt_uin)
	{
		return strtoupper(md5(strtoupper(md5(self::hex2asc(md5($password)) . self::hex2asc($pt_uin)) . $verification_str)));
	}
	
	/**
	 * 我们将\x00\x00\x00\x00\x3c\xcb\x48\x45分为00 00 00 00 3c cb 48 45
	 * 然后对每组16进制数字转换成ASCII字符，然后连接起来就是pt.uin
	 * @param string $str
	 * @return string
	 */
	public static function hex2asc($str)
	{
		$str = join('', explode('\x', $str));
		$len = strlen($str);
		$data = null;
		for ($i=0;$i<$len;$i+=2)
		{
			$data .= chr(hexdec(substr($str,$i,2)));
		}
		return $data;
	}
	
	/**
	 * 处理cookie文件
	 */
	public function parseCookie() 
	{
		$cookies = file($this->cookie_file);
		$data = array();
		foreach ($cookies as $v)
		{
			if (preg_match("/(.*\.qq\.com)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\n/U", $v, $p))
			{
				$data[] = array_slice($p, 1);
			}
		}
		$this->cookies = $data;
	}
	
	/**
	 * 读取cookie值
	 * @param string $cookie
	 * @return boolean|string
	 */
	public function getCookie($cookie)
	{
		if(empty($this->cookies))
			$this->parseCookie();
		if ($cookie === NULL)
		{
			return FALSE;
		}
		if (is_array($cookie) && count($cookie)<=6)
		{
			return FALSE;
		}
		foreach ($this->cookies as $v)
		{
			if ($v[5] === $cookie) {
				return $v[6];
			}
		}
	}

	// Uncomment the following methods and override them if needed
	/*
	public function filters()
	{
		// return the filter configuration for this controller, e.g.:
		return array(
			'inlineFilterName',
			array(
				'class'=>'path.to.FilterClass',
				'propertyName'=>'propertyValue',
			),
		);
	}

	public function actions()
	{
		// return external action classes, e.g.:
		return array(
			'action1'=>'path.to.ActionClass',
			'action2'=>array(
				'class'=>'path.to.AnotherActionClass',
				'propertyName'=>'propertyValue',
			),
		);
	}
	*/
}